using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;

namespace AliCMS.SystemModule.Bll
{
    public partial class Module : ObjectBase, IModule
    {
        public partial class Object : ObjectBase, SystemModule.Module.IObject
        {
            public class Property : ObjectBase, SystemModule.Module.Object.IProperty
            {
				public Property(int instanceID, string lang, bool checkRight, string database)
					: base(instanceID, lang, checkRight)
				{
				}

				public override object ExecuteService(HttpContext context)
				{
                    object result = null;

                    string operation = context.Request.QueryString["Operation"];
                    if (operation == "Add")
                    {
                        string ns = context.Request.QueryString["Namespace"];
                        int objectID = Convert.ToInt32(context.Request.QueryString["ObjectID"]);

                        Dictionary<string, object> item = new Dictionary<string, object>();
                        string value = null;
                        value = context.Request.Form["ID"];
                        if (value != null) item[Alias.Module.Object.Property.ID] = value;
                        value = context.Request.Form["Name"];
                        if (value != null) item[Alias.Module.Object.Property.Name] = value;
                        value = context.Request.Form["FieldName"];
                        if (value != null) item[Alias.Module.Object.Property.FieldName] = value;
                        value = context.Request.Form["IsNullable"];
                        if (value != null) item[Alias.Module.Object.Property.IsNullable] = value;
                        value = context.Request.Form["SqlDbDefault"];
                        if (value != null) item[Alias.Module.Object.Property.SqlDbDefault] = value;
                        value = context.Request.Form["OleDbDefault"];
                        if (value != null) item[Alias.Module.Object.Property.OleDbDefault] = value;
                        value = context.Request.Form["SqlDbType"];
                        if (value != null) item[Alias.Module.Object.Property.SqlDbType] = value;
                        value = context.Request.Form["OleDbType"];
                        if (value != null) item[Alias.Module.Object.Property.OleDbType] = value;
                        value = context.Request.Form["MaxLength"];
                        if (value != null) item[Alias.Module.Object.Property.MaxLength] = value;
                        value = context.Request.Form["NumericPrecision"];
                        if (value != null) item[Alias.Module.Object.Property.NumericPrecision] = value;
                        value = context.Request.Form["NumericScale"];
                        if (value != null) item[Alias.Module.Object.Property.NumericScale] = value;
                        value = context.Request.Form["IsIdentity"];
                        if (value != null) item[Alias.Module.Object.Property.IsIdentity] = value;
                        value = context.Request.Form["MultiLanguage"];
                        if (value != null) item[Alias.Module.Object.Property.MultiLanguage] = value;
                        value = context.Request.Form["PrimaryKey"];
                        if (value != null) item[Alias.Module.Object.Property.PrimaryKey] = value;
                        value = context.Request.Form["Unique"];
                        if (value != null) item[Alias.Module.Object.Property.Unique] = value;
                        value = context.Request.Form["IsMeta"];
                        if (value != null) item[Alias.Module.Object.Property.IsMeta] = value;
                        value = context.Request.Form["MainTableID"];
                        if (value != null) item[Alias.Module.Object.Property.MainTableID] = value;
                        value = context.Request.Form["MainFieldID"];
                        if (value != null) item[Alias.Module.Object.Property.MainFieldID] = value;
                        value = context.Request.Form["UpdateRule"];
                        if (value != null) item[Alias.Module.Object.Property.UpdateRule] = value;
                        value = context.Request.Form["DeleteRule"];
                        if (value != null) item[Alias.Module.Object.Property.DeleteRule] = value;
						value = context.Request.Form["Memo"];
						if (value != null) item[Alias.Module.Object.Property.Memo] = value;

						result = Add(ns, objectID, item);
					}
                    else if (operation == "Modify")
                    {
                        string ns = context.Request.QueryString["Namespace"];
                        int objectID = Convert.ToInt32(context.Request.QueryString["ObjectID"]);
                        int id = Convert.ToInt32(context.Request.QueryString["ID"]);

                        Dictionary<string, object> changes = new Dictionary<string, object>();
                        string value = null;
                        value = context.Request.Form["Name"];
                        if (value != null) changes[Alias.Module.Object.Property.Name] = value;
                        value = context.Request.Form["FieldName"];
                        if (value != null) changes[Alias.Module.Object.Property.FieldName] = value;
                        value = context.Request.Form["IsNullable"];
                        if (value != null) changes[Alias.Module.Object.Property.IsNullable] = value;
                        value = context.Request.Form["SqlDbDefault"];
                        if (value != null) changes[Alias.Module.Object.Property.SqlDbDefault] = value;
                        value = context.Request.Form["OleDbDefault"];
                        if (value != null) changes[Alias.Module.Object.Property.OleDbDefault] = value;
                        value = context.Request.Form["SqlDbType"];
                        if (value != null) changes[Alias.Module.Object.Property.SqlDbType] = value;
                        value = context.Request.Form["OleDbType"];
                        if (value != null) changes[Alias.Module.Object.Property.OleDbType] = value;
                        value = context.Request.Form["MaxLength"];
                        if (value != null) changes[Alias.Module.Object.Property.MaxLength] = value;
                        value = context.Request.Form["NumericPrecision"];
                        if (value != null) changes[Alias.Module.Object.Property.NumericPrecision] = value;
                        value = context.Request.Form["NumericScale"];
                        if (value != null) changes[Alias.Module.Object.Property.NumericScale] = value;
                        value = context.Request.Form["IsIdentity"];
                        if (value != null) changes[Alias.Module.Object.Property.IsIdentity] = value;
                        value = context.Request.Form["MultiLanguage"];
                        if (value != null) changes[Alias.Module.Object.Property.MultiLanguage] = value;
                        value = context.Request.Form["PrimaryKey"];
                        if (value != null) changes[Alias.Module.Object.Property.PrimaryKey] = value;
                        value = context.Request.Form["Unique"];
                        if (value != null) changes[Alias.Module.Object.Property.Unique] = value;
                        value = context.Request.Form["IsMeta"];
                        if (value != null) changes[Alias.Module.Object.Property.IsMeta] = value;
                        value = context.Request.Form["MainTableID"];
                        if (value != null) changes[Alias.Module.Object.Property.MainTableID] = value;
                        value = context.Request.Form["MainFieldID"];
                        if (value != null) changes[Alias.Module.Object.Property.MainFieldID] = value;
                        value = context.Request.Form["UpdateRule"];
                        if (value != null) changes[Alias.Module.Object.Property.UpdateRule] = value;
                        value = context.Request.Form["DeleteRule"];
                        if (value != null) changes[Alias.Module.Object.Property.DeleteRule] = value;
						value = context.Request.Form["Memo"];
						if (value != null) changes[Alias.Module.Object.Property.Memo] = value;

                        Modify(ns, objectID, id, changes);
                    }
                    else if (operation == "Delete")
                    {
                        string ns = context.Request.QueryString["Namespace"];
                        int objectID = Convert.ToInt32(context.Request.QueryString["ObjectID"]);
                        int id = Convert.ToInt32(context.Request.QueryString["ID"]);

                        Delete(ns, objectID, id);
                    }
                    else if (operation == "Move")
                    {
                        string ns = context.Request.QueryString["Namespace"];
                        int objectID = Convert.ToInt32(context.Request.QueryString["ObjectID"]);
                        int from = Convert.ToInt32(context.Request.QueryString["From"]);
                        int to = Convert.ToInt32(context.Request.QueryString["To"]);

                        Move(ns, objectID, from, to);
                    }
                    else if (operation == "List")
                    {
                        result = HandleCommonList(context);
                    }
                    else
                    {
                        throw new Exception("lang_header_param");
                    }

                    return result;
                }

				public Dictionary<string, object> Get(string ns, int objectID, int id)
                {
                    if (CheckRight)
                    {
                        ValidateRight("Get", Guid.Empty);
                    }

                    string path = Manager.MapPath(Manager.GetModulePath(ns) + "module.config");
                    if (!File.Exists(path))
                    {
                        Exception exp = new Exception("lang_module_not_exist");
                        exp.Data.Add(1, ns);
                        throw exp;
                    }

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(path);
                    XmlNode node = xmlDoc.SelectSingleNode("//Objects//Object[InnerID=" + objectID + "]/Properties/Property[InnerID=" + id + "]");
                    if (node == null)
                    {
                        Exception exp = new Exception("lang_property_not_exist");
                        exp.Data.Add(1, ns);
                        exp.Data.Add(2, objectID);
                        exp.Data.Add(3, id);
                        throw exp;
                    }

                    Dictionary<string, object> result = new Dictionary<string, object>();
                    result[Alias.Module.Object.Property.ID] = node.SelectSingleNode("ID").InnerText;
                    result[Alias.Module.Object.Property.ObjectID] = node.ParentNode.ParentNode.SelectSingleNode("ID").InnerText;
                    result[Alias.Module.Object.Property.Name] = node.SelectSingleNode("Name").InnerText;
                    result[Alias.Module.Object.Property.FieldName] = node.SelectSingleNode("FieldName").InnerText;
                    result[Alias.Module.Object.Property.IsNullable] = node.SelectSingleNode("IsNullable").InnerText;
                    result[Alias.Module.Object.Property.SqlDbDefault] = node.SelectSingleNode("SqlDbDefault").InnerText;
                    result[Alias.Module.Object.Property.OleDbDefault] = node.SelectSingleNode("OleDbDefault").InnerText;
                    result[Alias.Module.Object.Property.SqlDbType] = node.SelectSingleNode("SqlDbType").InnerText;
                    result[Alias.Module.Object.Property.OleDbType] = node.SelectSingleNode("OleDbType").InnerText;
                    result[Alias.Module.Object.Property.MaxLength] = node.SelectSingleNode("MaxLength").InnerText;
                    result[Alias.Module.Object.Property.NumericPrecision] = node.SelectSingleNode("NumericPrecision").InnerText;
                    result[Alias.Module.Object.Property.NumericScale] = node.SelectSingleNode("NumericScale").InnerText;
                    result[Alias.Module.Object.Property.IsIdentity] = node.SelectSingleNode("IsIdentity").InnerText;
                    result[Alias.Module.Object.Property.MultiLanguage] = node.SelectSingleNode("MultiLanguage").InnerText;
                    result[Alias.Module.Object.Property.PrimaryKey] = node.SelectSingleNode("PrimaryKey").InnerText;
                    result[Alias.Module.Object.Property.Unique] = node.SelectSingleNode("Unique").InnerText;
                    if (node.SelectSingleNode("IsMeta") == null)
                        result[Alias.Module.Object.Property.IsMeta] = false;
                    else
                        result[Alias.Module.Object.Property.IsMeta] = Convert.ToBoolean(node.SelectSingleNode("IsMeta").InnerText);
                    if (String.IsNullOrEmpty(node.SelectSingleNode("MainTableID").InnerText))
                        result[Alias.Module.Object.Property.MainTableID] = node.SelectSingleNode("MainTableID").InnerText;
                    else
                        result[Alias.Module.Object.Property.MainTableID] = new Guid(node.SelectSingleNode("MainTableID").InnerText);
                    if (String.IsNullOrEmpty(node.SelectSingleNode("MainFieldID").InnerText))
                        result[Alias.Module.Object.Property.MainFieldID] = node.SelectSingleNode("MainFieldID").InnerText;
                    else
                        result[Alias.Module.Object.Property.MainFieldID] = new Guid(node.SelectSingleNode("MainFieldID").InnerText);
                    result[Alias.Module.Object.Property.UpdateRule] = node.SelectSingleNode("UpdateRule").InnerText;
                    result[Alias.Module.Object.Property.DeleteRule] = node.SelectSingleNode("DeleteRule").InnerText;

					XmlNode memoNode = node.SelectSingleNode("Memo");
					if (memoNode != null)
						result[Alias.Module.Object.Property.Memo] = memoNode.InnerText;
					else
						result[Alias.Module.Object.Property.Memo] = "";

					return result;
                }
				public Guid Add(string ns, int objectID, Dictionary<string, object> item)
                {
                    if (CheckRight)
                    {
                        ValidateRight("Add", Guid.Empty);
                    }

                    string path = Manager.MapPath(Manager.GetModulePath(ns) + "module.config");
                    if (!File.Exists(path))
                    {
                        Exception exp = new Exception("lang_module_not_exist");
                        exp.Data.Add(1, ns);
                        throw exp;
                    }

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(path);
                    XmlNode objectNode = xmlDoc.SelectSingleNode("//Objects//Object[InnerID=" + objectID + "]");
                    if (objectNode == null)
                    {
                        Exception exp = new Exception("lang_object_not_exist");
                        exp.Data.Add(1, ns);
                        exp.Data.Add(2, objectID);
                        throw exp;
                    }

                    XmlNode parentNode = objectNode.SelectSingleNode("Properties");
                    if (parentNode == null)
                    {
                        parentNode = xmlDoc.CreateElement("Properties");
                        objectNode.AppendChild(parentNode);
                    }

                    XmlNode propertyNode = xmlDoc.CreateElement("Property");
                    parentNode.AppendChild(propertyNode);

                    XmlNode node = null;

                    node = xmlDoc.CreateElement("ID");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.ID) && !String.IsNullOrEmpty(Convert.ToString(item[Alias.Module.Object.Property.ID])))
                        node.InnerText = item[Alias.Module.Object.Property.ID].ToString();
                    else
                        node.InnerText = Guid.NewGuid().ToString();
                    Guid guid = new Guid(node.InnerText);

                    node = xmlDoc.CreateElement("InnerID");
                    int innerID = xmlDoc.SelectNodes("//Property").Count + 1;
                    while (xmlDoc.SelectSingleNode("//Property[InnerID=" + innerID + "]") != null)
                    {
                        innerID++;
                    }
                    node.InnerText = Convert.ToString(innerID);
                    propertyNode.AppendChild(node);

                    node = xmlDoc.CreateElement("Name");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.Name))
                        node.InnerText = item[Alias.Module.Object.Property.Name].ToString();

                    node = xmlDoc.CreateElement("FieldName");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.FieldName))
                        node.InnerText = item[Alias.Module.Object.Property.FieldName].ToString();

                    node = xmlDoc.CreateElement("IsNullable");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.IsNullable))
                        node.InnerText = item[Alias.Module.Object.Property.IsNullable].ToString();

                    node = xmlDoc.CreateElement("SqlDbDefault");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.SqlDbDefault))
                        node.InnerText = item[Alias.Module.Object.Property.SqlDbDefault].ToString();

                    node = xmlDoc.CreateElement("OleDbDefault");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.OleDbDefault))
                        node.InnerText = item[Alias.Module.Object.Property.OleDbDefault].ToString();

                    node = xmlDoc.CreateElement("SqlDbType");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.SqlDbType))
                        node.InnerText = item[Alias.Module.Object.Property.SqlDbType].ToString();

                    node = xmlDoc.CreateElement("OleDbType");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.OleDbType))
                        node.InnerText = item[Alias.Module.Object.Property.OleDbType].ToString();

                    node = xmlDoc.CreateElement("MaxLength");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.MaxLength))
                        node.InnerText = item[Alias.Module.Object.Property.MaxLength].ToString();

                    node = xmlDoc.CreateElement("NumericPrecision");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.NumericPrecision))
                        node.InnerText = item[Alias.Module.Object.Property.NumericPrecision].ToString();

                    node = xmlDoc.CreateElement("NumericScale");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.NumericScale))
                        node.InnerText = item[Alias.Module.Object.Property.NumericScale].ToString();

                    node = xmlDoc.CreateElement("IsIdentity");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.IsIdentity))
                        node.InnerText = item[Alias.Module.Object.Property.IsIdentity].ToString();

                    node = xmlDoc.CreateElement("MultiLanguage");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.MultiLanguage))
                        node.InnerText = item[Alias.Module.Object.Property.MultiLanguage].ToString();

                    node = xmlDoc.CreateElement("PrimaryKey");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.PrimaryKey))
                        node.InnerText = item[Alias.Module.Object.Property.PrimaryKey].ToString();

                    node = xmlDoc.CreateElement("Unique");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.Unique))
                        node.InnerText = item[Alias.Module.Object.Property.Unique].ToString();

                    node = xmlDoc.CreateElement("IsMeta");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.IsMeta))
                        node.InnerText = item[Alias.Module.Object.Property.IsMeta].ToString();

                    node = xmlDoc.CreateElement("MainTableID");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.MainTableID))
                        node.InnerText = item[Alias.Module.Object.Property.MainTableID].ToString();

                    node = xmlDoc.CreateElement("MainFieldID");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.MainFieldID))
                        node.InnerText = item[Alias.Module.Object.Property.MainFieldID].ToString();

                    node = xmlDoc.CreateElement("UpdateRule");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.UpdateRule))
                        node.InnerText = item[Alias.Module.Object.Property.UpdateRule].ToString();

                    node = xmlDoc.CreateElement("DeleteRule");
                    propertyNode.AppendChild(node);
                    if (item.ContainsKey(Alias.Module.Object.Property.DeleteRule))
                        node.InnerText = item[Alias.Module.Object.Property.DeleteRule].ToString();

                    node = xmlDoc.CreateElement("Memo");
                    propertyNode.AppendChild(node);
					if (item.ContainsKey(Alias.Module.Object.Property.Memo))
						node.InnerText = item[Alias.Module.Object.Property.Memo].ToString();

                    xmlDoc.Save(path);

                    return guid;
                }
				public void Modify(string ns, int objectID, int id, Dictionary<string, object> changes)
                {
                    if (CheckRight)
                    {
                        ValidateRight("Modify", Guid.Empty);
                    }

                    string path = Manager.MapPath(Manager.GetModulePath(ns) + "module.config");
                    if (!File.Exists(path))
                    {
                        Exception exp = new Exception("lang_module_not_exist");
                        exp.Data.Add(1, ns);
                        throw exp;
                    }

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(path);
                    XmlNode propertyNode = xmlDoc.SelectSingleNode("//Objects//Object[InnerID=" + objectID + "]/Properties/Property[InnerID=" + id + "]");
                    if (propertyNode == null)
                    {
                        Exception exp = new Exception("lang_property_not_exist");
                        exp.Data.Add(1, ns);
                        exp.Data.Add(2, objectID);
                        exp.Data.Add(3, id);
                        throw exp;
                    }

                    XmlNode node = null;

                    if (changes.ContainsKey(Alias.Module.Object.Property.Name))
                    {
                        node = propertyNode.SelectSingleNode("Name");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("Name");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.Name].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.FieldName))
                    {
                        node = propertyNode.SelectSingleNode("FieldName");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("FieldName");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.FieldName].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.IsNullable))
                    {
                        node = propertyNode.SelectSingleNode("IsNullable");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("IsNullable");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.IsNullable].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.SqlDbDefault))
                    {
                        node = propertyNode.SelectSingleNode("SqlDbDefault");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("SqlDbDefault");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.SqlDbDefault].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.OleDbDefault))
                    {
                        node = propertyNode.SelectSingleNode("OleDbDefault");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("OleDbDefault");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.OleDbDefault].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.SqlDbType))
                    {
                        node = propertyNode.SelectSingleNode("SqlDbType");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("SqlDbType");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.SqlDbType].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.OleDbType))
                    {
                        node = propertyNode.SelectSingleNode("OleDbType");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("OleDbType");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.OleDbType].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.MaxLength))
                    {
                        node = propertyNode.SelectSingleNode("MaxLength");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("MaxLength");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.MaxLength].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.NumericPrecision))
                    {
                        node = propertyNode.SelectSingleNode("NumericPrecision");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("NumericPrecision");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.NumericPrecision].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.NumericScale))
                    {
                        node = propertyNode.SelectSingleNode("NumericScale");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("NumericScale");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.NumericScale].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.IsIdentity))
                    {
                        node = propertyNode.SelectSingleNode("IsIdentity");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("IsIdentity");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.IsIdentity].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.MultiLanguage))
                    {
                        node = propertyNode.SelectSingleNode("MultiLanguage");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("MultiLanguage");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.MultiLanguage].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.PrimaryKey))
                    {
                        node = propertyNode.SelectSingleNode("PrimaryKey");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("PrimaryKey");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.PrimaryKey].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.Unique))
                    {
                        node = propertyNode.SelectSingleNode("Unique");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("Unique");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.Unique].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.IsMeta))
                    {
                        node = propertyNode.SelectSingleNode("IsMeta");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("IsMeta");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.IsMeta].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.MainTableID))
                    {
                        node = propertyNode.SelectSingleNode("MainTableID");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("MainTableID");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.MainTableID].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.MainFieldID))
                    {
                        node = propertyNode.SelectSingleNode("MainFieldID");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("MainFieldID");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.MainFieldID].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.UpdateRule))
                    {
                        node = propertyNode.SelectSingleNode("UpdateRule");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("UpdateRule");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.UpdateRule].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.DeleteRule))
                    {
                        node = propertyNode.SelectSingleNode("DeleteRule");
                        if (node == null)
                        {
                            node = xmlDoc.CreateElement("DeleteRule");
                            propertyNode.AppendChild(node);
                        }
                        node.InnerText = changes[Alias.Module.Object.Property.DeleteRule].ToString();
                    }

                    if (changes.ContainsKey(Alias.Module.Object.Property.Memo))
                    {
						node = propertyNode.SelectSingleNode("Memo");
                        if (node == null)
                        {
							node = xmlDoc.CreateElement("Memo");
                            propertyNode.AppendChild(node);
                        }
						node.InnerText = changes[Alias.Module.Object.Property.Memo].ToString();
                    }

                    xmlDoc.Save(path);
                }
				public void Delete(string ns, int objectID, int id)
                {
                    if (CheckRight)
                    {
                        ValidateRight("Delete", Guid.Empty);
                    }

                    string path = Manager.MapPath(Manager.GetModulePath(ns) + "module.config");
                    if (!File.Exists(path))
                    {
                        Exception exp = new Exception("lang_module_not_exist");
                        exp.Data.Add(1, ns);
                        throw exp;
                    }

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(path);
                    XmlNode node = xmlDoc.SelectSingleNode("//Objects//Object[InnerID=" + objectID + "]/Properties/Property[InnerID=" + id + "]");
                    if (node == null)
                    {
                        Exception exp = new Exception("lang_property_not_exist");
                        exp.Data.Add(1, ns);
                        exp.Data.Add(2, objectID);
                        exp.Data.Add(3, id);
                        throw exp;
                    }

                    node.ParentNode.RemoveChild(node);

                    xmlDoc.Save(path);
                }
				public void Move(string ns, int objectID, int from, int to)
                {
                    if (CheckRight)
                    {
                        ValidateRight("Move", Guid.Empty);
                    }

                    string path = Manager.MapPath(Manager.GetModulePath(ns) + "module.config");
                    if (!File.Exists(path))
                    {
                        Exception exp = new Exception("lang_module_not_exist");
                        exp.Data.Add(1, ns);
                        throw exp;
                    }

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(path);

                    XmlNode fromNode = xmlDoc.SelectSingleNode("//Objects//Object[InnerID=" + objectID + "]/Properties/Property[InnerID=" + from + "]");
                    if (fromNode == null)
                    {
                        Exception exp = new Exception("lang_property_not_exist");
                        exp.Data.Add(1, ns);
                        exp.Data.Add(2, String.Empty);
                        exp.Data.Add(3, from);
                        throw exp;
                    }

                    XmlNode toNode = xmlDoc.SelectSingleNode("//Objects//Object[InnerID=" + objectID + "]/Properties/Property[InnerID=" + to + "]");
                    if (toNode == null)
                    {
                        Exception exp = new Exception("lang_property_not_exist");
                        exp.Data.Add(1, ns);
                        exp.Data.Add(2, String.Empty);
                        exp.Data.Add(3, to);
                        throw exp;
                    }

                    toNode.ParentNode.InsertBefore(fromNode, toNode);

                    xmlDoc.Save(path);
                }
				public DataTable List(int page, int pageSize, Dictionary<string, object> condition, Dictionary<string, string> sort)
				{
					return _List(page, pageSize, condition, sort);
				}
				protected override DataTable _List(int page, int pageSize, Dictionary<string, object> condition, Dictionary<string, string> sort)
                {
                    if (CheckRight)
                    {
                        ValidateRight("List", Guid.Empty);
                    }

                    string root = Manager.MapPath(Manager.GetModulePath(null));
                    if (!Directory.Exists(root))
                        throw new Exception("lang_module_directory_not_exist");

                    DataTable result = new DataTable();
                    result.Columns.Add(Alias.Module.Object.Property.ID, typeof(Guid));
                    result.Columns.Add(Alias.Module.Object.Property.InnerID, typeof(int));
                    result.Columns.Add(Alias.Module.Object.Property.UniqueInnerID, typeof(string));
                    result.Columns.Add(Alias.Module.Object.Property.ObjectID, typeof(Guid));
                    result.Columns.Add(Alias.Module.Object.Property.Name, typeof(string));
                    result.Columns.Add(Alias.Module.Object.Property.FieldName, typeof(string));
                    result.Columns.Add(Alias.Module.Object.Property.IsNullable, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.SqlDbDefault, typeof(string));
                    result.Columns.Add(Alias.Module.Object.Property.OleDbDefault, typeof(string));
                    result.Columns.Add(Alias.Module.Object.Property.SqlDbType, typeof(int));
                    result.Columns.Add(Alias.Module.Object.Property.OleDbType, typeof(int));
                    result.Columns.Add(Alias.Module.Object.Property.MaxLength, typeof(int));
                    result.Columns.Add(Alias.Module.Object.Property.NumericPrecision, typeof(int));
                    result.Columns.Add(Alias.Module.Object.Property.NumericScale, typeof(int));
                    result.Columns.Add(Alias.Module.Object.Property.IsIdentity, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.MultiLanguage, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.PrimaryKey, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.Unique, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.IsMeta, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.MainTableID, typeof(Guid));
                    result.Columns.Add(Alias.Module.Object.Property.MainFieldID, typeof(Guid));
                    result.Columns.Add(Alias.Module.Object.Property.UpdateRule, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.DeleteRule, typeof(bool));
                    result.Columns.Add(Alias.Module.Object.Property.Memo, typeof(string));

                    int curIndex = 0, rowIndex = 0;
                    int startIndex = (page - 1) * pageSize;

                    XmlDocument xmlDoc = new XmlDocument();

                    string[] modules = Directory.GetFiles(root, "module.config", SearchOption.AllDirectories);
                    foreach (string file in modules)
                    {
                        string ns = Path.GetDirectoryName(file).Substring(root.Length);
                        if (condition != null && condition.ContainsKey(Alias.Module.Object.Property.Namespace) && condition[Alias.Module.Object.Property.Namespace].ToString() != ns)
                            continue;

                        int moduleID = 0;
                        foreach (char c in ns)
                        {
                            moduleID += c;
                        }

                        xmlDoc.Load(file);

                        string objectCondition = null;
                        if (condition != null)
                        {
                            if (condition.ContainsKey(Alias.Module.Object.Property.ObjectInnerID))
                                objectCondition = "InnerID='" + condition[Alias.Module.Object.Property.ObjectInnerID] + "'";

                            if (condition.ContainsKey(Alias.Module.Object.Property.ObjectID))
                            {
                                if (objectCondition != null)
                                    objectCondition += " and ";

                                objectCondition += "contains(translate(ID, 'abcdef', 'ABCDEF'), '" + condition[Alias.Module.Object.Property.ObjectID].ToString().Trim(new char[] { '{', '}' }).ToUpper() + "')";
                            }

                            if (objectCondition != null)
                                objectCondition = "[" + objectCondition + "]";
                        }

                        XmlNodeList objectNodeList = xmlDoc.SelectNodes("//Objects//Object" + objectCondition);
                        foreach (XmlNode objectNode in objectNodeList)
                        {
                            XmlNodeList nodeList = objectNode.SelectNodes("Properties/Property");
                            foreach (XmlNode node in nodeList)
                            {
                                Guid id = new Guid(node.SelectSingleNode("ID").InnerText);
                                int innerID = Convert.ToInt32(node.SelectSingleNode("InnerID").InnerText);

                                if (condition != null)
                                {
                                    if (condition.ContainsKey(Alias.Module.Object.Property.InnerID) && Convert.ToInt32(condition[Alias.Module.Object.Property.InnerID]) == innerID)
                                        continue;

                                    if (condition.ContainsKey(Alias.Module.Object.Property.ID) && !Guid.Equals(condition[Alias.Module.Object.Property.ID], id))
                                        continue;
                                }

                                if (pageSize != -1)
                                {
                                    if (curIndex < startIndex)
                                    {
                                        curIndex++;
                                        continue;
                                    }

                                    if (rowIndex == pageSize)
                                        goto Exit;
                                }

                                DataRow row = result.NewRow();
                                row[Alias.Module.Object.Property.ID] = id;
                                row[Alias.Module.Object.Property.InnerID] = innerID;
                                row[Alias.Module.Object.Property.UniqueInnerID] = "P" + moduleID + "_" + node.ParentNode.ParentNode.SelectSingleNode("InnerID").InnerText + "_" + innerID;
                                row[Alias.Module.Object.Property.ObjectID] = node.ParentNode.ParentNode.SelectSingleNode("ID").InnerText;
                                row[Alias.Module.Object.Property.Name] = node.SelectSingleNode("Name").InnerText;
                                row[Alias.Module.Object.Property.FieldName] = node.SelectSingleNode("FieldName").InnerText;
                                row[Alias.Module.Object.Property.IsNullable] = node.SelectSingleNode("IsNullable").InnerText;
                                row[Alias.Module.Object.Property.SqlDbDefault] = node.SelectSingleNode("SqlDbDefault").InnerText;
                                row[Alias.Module.Object.Property.OleDbDefault] = node.SelectSingleNode("OleDbDefault").InnerText;
                                row[Alias.Module.Object.Property.SqlDbType] = node.SelectSingleNode("SqlDbType").InnerText;
                                row[Alias.Module.Object.Property.OleDbType] = node.SelectSingleNode("OleDbType").InnerText;
                                row[Alias.Module.Object.Property.MaxLength] = node.SelectSingleNode("MaxLength").InnerText;
                                row[Alias.Module.Object.Property.NumericPrecision] = node.SelectSingleNode("NumericPrecision").InnerText;
                                row[Alias.Module.Object.Property.NumericScale] = node.SelectSingleNode("NumericScale").InnerText;
                                row[Alias.Module.Object.Property.IsIdentity] = node.SelectSingleNode("IsIdentity").InnerText;
                                row[Alias.Module.Object.Property.MultiLanguage] = node.SelectSingleNode("MultiLanguage").InnerText;
                                row[Alias.Module.Object.Property.PrimaryKey] = node.SelectSingleNode("PrimaryKey").InnerText;
                                row[Alias.Module.Object.Property.Unique] = node.SelectSingleNode("Unique").InnerText;
                                if (node.SelectSingleNode("IsMeta") == null)
                                    row[Alias.Module.Object.Property.IsMeta] = false;
                                else
                                    row[Alias.Module.Object.Property.IsMeta] = Convert.ToBoolean(node.SelectSingleNode("IsMeta").InnerText);
                                string mainTableID = node.SelectSingleNode("MainTableID").InnerText;
                                if (String.IsNullOrEmpty(mainTableID))
                                    row[Alias.Module.Object.Property.MainTableID] = Guid.Empty;
                                else
                                    row[Alias.Module.Object.Property.MainTableID] = new Guid(mainTableID);
                                string mainFieldID = node.SelectSingleNode("MainFieldID").InnerText;
                                if (String.IsNullOrEmpty(mainFieldID))
                                    row[Alias.Module.Object.Property.MainFieldID] = Guid.Empty;
                                else
                                    row[Alias.Module.Object.Property.MainFieldID] = new Guid(mainFieldID);
                                row[Alias.Module.Object.Property.UpdateRule] = node.SelectSingleNode("UpdateRule").InnerText;
                                row[Alias.Module.Object.Property.DeleteRule] = node.SelectSingleNode("DeleteRule").InnerText;

								XmlNode memoNode = node.SelectSingleNode("Memo");
								if (memoNode != null)
									row[Alias.Module.Object.Property.Memo] = memoNode.InnerText;
                                
								result.Rows.Add(row);

                                rowIndex++;
                            }
                        }
                    }

                    Exit:
                    return result;
                }
				public DataTable List(int page, int pageSize, string condition, string sort)
                {
                    Dictionary<string, object> newCondition = null;
                    if (!String.IsNullOrEmpty(condition))
                    {
                        newCondition = new Dictionary<string, object>();
                        string[] conditions = condition.Split(new string[] { " and ", " AND " }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string c in conditions)
                        {
                            string[] pair = c.Split('=');
                            newCondition[pair[0]] = pair[1];
                        }
                    }

                    return List(page, pageSize, newCondition, (Dictionary<string, string>)null);
                }
				public int GetRecordCount(Dictionary<string, object> condition)
                {
                    DataTable result = _List(-1, -1, condition, null);
                    return result.Rows.Count;
                }
				public int GetRecordCount(string condition)
                {
                    Dictionary<string, object> newCondition = null;
                    if (!String.IsNullOrEmpty(condition))
                    {
                        newCondition = new Dictionary<string, object>();
                        string[] conditions = condition.Split(new string[] { " and ", " AND " }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string c in conditions)
                        {
                            string[] pair = c.Split('=');
                            newCondition[pair[0]] = pair[1];
                        }
                    }

                    return GetRecordCount(newCondition);
                }
            }
        }
    }
}
